package com.transfer.http.download.MultiThread.task;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.concurrent.Callable;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.transfer.common.SuspendInterface;
import com.transfer.http.download.taskInterface.FileSliceDownloadTask;

public class FileMergeTask implements Callable<Boolean>, SuspendInterface {
  private static final Logger log = LoggerFactory.getLogger(FileMergeTask.class);
  private FileSliceDownloadTask[] childTasks;
  private int numThread;
  private String fileDir;
  private String fileName;
  private long fileLength;
  private long taskId;
  private boolean statusError;
  private long mergeFlushSize;

  private boolean shutdownRequested=false;
  public FileMergeTask(FileSliceDownloadTask[] childTasks, int numThread, String fileDir,
      String fileName, long taskId, boolean statusError, long mergeFlushSize, long fileLength) {
    this.childTasks = childTasks;
    this.numThread=numThread;
    this.fileDir = fileDir;
    this.fileName = fileName;
    this.taskId = taskId;
    this.statusError = statusError;
    this.mergeFlushSize = mergeFlushSize;
    this.fileLength = fileLength;
  }
  public Boolean call() throws Exception {
    log.info("taskId: "+taskId+" 开始合并文件！");
    boolean checkFileSuccess=checkFile(fileDir, fileName, fileLength);
    System.out.println(checkFileSuccess);
    if(!checkFileSuccess)
      return false;
    boolean mergeSuccess=tempFileToTargetFile(childTasks, numThread, fileDir, fileName, taskId, statusError,
        mergeFlushSize);
    if(!mergeSuccess)
      return false;
    return true;
  }

  private boolean checkFile(String fileDir, String fileName, long contentLength) {
    File file = new File(fileDir + fileName);
    long localFileSize = file.length();

    if (file.exists()) {
      log.info("任务id： " + this.taskId + "; file " + fileName + " has exists!");
      if (localFileSize < contentLength) {
        log.info("任务id： " + this.taskId + "; file " + fileName
            + " has exists,but not sucess, so delete it!");
        file.delete();
        return createNewFile(file);
      } else {
        log.info("任务id： " + this.taskId + "; file " + fileName + " has download success!");
      }
    } else {
      return createNewFile(file);
    }
    return false;
  }

  private boolean createNewFile(File file) {
    try {
      file.createNewFile();
    } catch (IOException e) {
      log.info("创建文件失败  for taskId: " + taskId);
      return false;
    }
    return true;
  }

  private boolean tempFileToTargetFile(FileSliceDownloadTask[] childTasks, int numThread,
      String fileDir, String fileName, long taskId, boolean statusError, long mergeFlushSize) {
    try {
      BufferedOutputStream outputStream =
          new BufferedOutputStream(new FileOutputStream(fileDir + fileName));

      
      System.out.println("statusError: "+statusError);
      System.out.println("numThread: "+numThread);
      for (int i = 0; i < numThread; i++) {
        if(shutdownRequested)//如果正在合并文件时候接收到暂停任务
          break;
        if (statusError) {
          for (int k = 0; k < numThread; k++) {
            if (childTasks[k].getTempFile().length() == 0)
              childTasks[k].getTempFile().delete();
          }
          log.info("errorStatus of taskId: " + taskId + "; 子任务id");
          break;
        }
        System.out.println("file: "+childTasks[i].getTempFile());
        BufferedInputStream inputStream =
            new BufferedInputStream(new FileInputStream(childTasks[i].getTempFile()));
        log.info("Now merge the file of taskId: " + taskId + "; 子任务id" + childTasks[i].getId());
        int len = 0;
        long count = 0;
        byte[] b = new byte[1024];
        while (!shutdownRequested&&(len = inputStream.read(b)) != -1) {
          count += len;
          outputStream.write(b, 0, len);
          if ((count % mergeFlushSize) == 0) {
            outputStream.flush();
          }
        }
        inputStream.close();
        if (childTasks[i].getStatus() == FileSliceDownloadTask.STATUS_HAS_FINISHED) {
          childTasks[i].getTempFile().delete();
        }
      }
      outputStream.flush();
      outputStream.close();
      return true;
    } catch (FileNotFoundException e) {
      log.info("taskId: " + taskId + "合并文件时候没有找到文件！" + e);
    } catch (IOException e) {
      log.info("taskId: " + taskId + "合并文件时候发生异常！" + e);
    }
    return false;
  }
  public void shutdownRequest() {
    shutdownRequested = true;
  }
}
